home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / SOURCE / LIBPNG / PNGPREAD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-16  |  29.9 KB  |  1,083 lines  |  [TEXT/CWIE]

  1.  
  2. /* pngpread.c - read a png file in push mode
  3.  
  4.    libpng 1.0 beta 4 - version 0.90
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    January 10, 1997
  8.    */
  9.  
  10. #define PNG_INTERNAL
  11. #include "png.h"
  12.  
  13. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  14.  
  15. void
  16. png_process_data(png_structp png_ptr, png_infop info_ptr,
  17.    png_bytep buffer, png_uint_32 buffer_size)
  18. {
  19.    png_push_restore_buffer(png_ptr, buffer, buffer_size);
  20.  
  21.    while (png_ptr->buffer_size)
  22.    {
  23.       png_process_some_data(png_ptr, info_ptr);
  24.    }
  25. }
  26.  
  27. /* What we do with the incoming data depends on what we were previously
  28.  * doing before we ran out of data...
  29.  */
  30. void
  31. png_process_some_data(png_structp png_ptr, png_infop info_ptr)
  32. {
  33.    switch (png_ptr->process_mode)
  34.    {
  35.       case PNG_READ_SIG_MODE:
  36.       {
  37.          png_push_read_sig(png_ptr, info_ptr);
  38.          break;
  39.       }
  40.       case PNG_READ_CHUNK_MODE:
  41.       {
  42.          png_push_read_chunk(png_ptr, info_ptr);
  43.          break;
  44.       }
  45.       case PNG_READ_IDAT_MODE:
  46.       {
  47.          png_push_read_IDAT(png_ptr);
  48.          break;
  49.       }
  50. #if defined(PNG_READ_tEXt_SUPPORTED)
  51.       case PNG_READ_tEXt_MODE:
  52.       {
  53.          png_push_read_tEXt(png_ptr, info_ptr);
  54.          break;
  55.       }
  56. #endif
  57. #if defined(PNG_READ_zTXt_SUPPORTED)
  58.       case PNG_READ_zTXt_MODE:
  59.       {
  60.          png_push_read_zTXt(png_ptr, info_ptr);
  61.          break;
  62.       }
  63. #endif
  64.       case PNG_READ_END_MODE:
  65.       {
  66.          png_push_read_chunk(png_ptr, info_ptr);
  67.          break;
  68.       }
  69.       case PNG_SKIP_MODE:
  70.       {
  71.          png_push_skip(png_ptr);
  72.          break;
  73.       }
  74.       default:
  75.       {
  76.          png_ptr->buffer_size = 0;
  77.          break;
  78.       }
  79.    }
  80. }
  81.  
  82. /* Read any remaining signature bytes from the stream and compare them with
  83.  * the correct PNG signature.  It is possible that this routine is called
  84.  * with bytes already read from the signature, whether because they have been
  85.  * checked by the calling application, or from multiple calls to this routine.
  86.  */
  87. void
  88. png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
  89. {
  90.    int num_checked = png_ptr->sig_bytes,
  91.         num_to_check = 8 - num_checked;
  92.  
  93.    if (png_ptr->buffer_size < num_to_check)
  94.    {
  95.       num_to_check = png_ptr->buffer_size;
  96.    }
  97.  
  98.    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), 
  99.       (png_uint_32)num_to_check);
  100.    png_ptr->sig_bytes += num_to_check;
  101.  
  102.    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
  103.    {
  104.       if (num_checked < 4 &&
  105.           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
  106.          png_error(png_ptr, "Not a PNG file");
  107.       else
  108.          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
  109.    }
  110.    else
  111.    {
  112.       if (png_ptr->sig_bytes >= 8)
  113.       {
  114.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  115.       }
  116.    }
  117. }
  118.  
  119. void
  120. png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
  121. {
  122.    /* First we make sure we have enough data for the 4 byte chunk name
  123.       and the 4 byte chunk length before proceeding with decoding the
  124.       chunk data.  To fully decode each of these chunks, we also make
  125.       sure we have enough data in the buffer for the 4 byte CRC at the
  126.       end of every chunk (except IDAT, which is handled separately). */
  127.    if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
  128.    {
  129.       png_byte chunk_length[4];
  130.  
  131.       if (png_ptr->buffer_size < 8)
  132.       {
  133.          png_push_save_buffer(png_ptr);
  134.          return;
  135.       }
  136.  
  137.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  138.       png_ptr->push_length = png_get_uint_32(chunk_length);
  139.       png_reset_crc(png_ptr);
  140.       png_push_fill_buffer(png_ptr, png_ptr->chunk_name, 4);
  141.       png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
  142.       png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
  143.    }
  144.  
  145.    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
  146.    {
  147.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  148.       {
  149.          png_push_save_buffer(png_ptr);
  150.          return;
  151.       }
  152.  
  153.       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
  154.    }
  155.    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
  156.    {
  157.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  158.       {
  159.          png_push_save_buffer(png_ptr);
  160.          return;
  161.       }
  162.  
  163.       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
  164.    }
  165.    else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  166.    {
  167.       /* If we reach an IDAT chunk, this means we have read all of the
  168.          header chunks, and we can start reading the image (or if this
  169.          is called after the image has been read - we have an error). */
  170.       if (png_ptr->mode & PNG_HAVE_IDAT)
  171.       {
  172.          if (png_ptr->push_length == 0)
  173.             return;
  174.  
  175.          if (png_ptr->mode & PNG_AFTER_IDAT)
  176.             png_error(png_ptr, "Too many IDAT's found");
  177.       }
  178.  
  179.       png_ptr->idat_size = png_ptr->push_length;
  180.       png_ptr->mode |= PNG_HAVE_IDAT;
  181.       png_ptr->process_mode = PNG_READ_IDAT_MODE;
  182.       png_push_have_info(png_ptr, info_ptr);
  183.       png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
  184.       png_ptr->zstream.next_out = png_ptr->row_buf;
  185.       return;
  186.    }
  187.    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
  188.    {
  189.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  190.       {
  191.          png_push_save_buffer(png_ptr);
  192.          return;
  193.       }
  194.  
  195.       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
  196.       png_ptr->process_mode = PNG_READ_DONE_MODE;
  197.       png_push_have_end(png_ptr, info_ptr);
  198.    }
  199. #if defined(PNG_READ_gAMA_SUPPORTED)
  200.    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
  201.    {
  202.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  203.       {
  204.          png_push_save_buffer(png_ptr);
  205.          return;
  206.       }
  207.  
  208.       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
  209.    }
  210. #endif
  211. #if defined(PNG_READ_sBIT_SUPPORTED)
  212.    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
  213.    {
  214.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  215.       {
  216.          png_push_save_buffer(png_ptr);
  217.          return;
  218.       }
  219.  
  220.       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
  221.    }
  222. #endif
  223. #if defined(PNG_READ_cHRM_SUPPORTED)
  224.    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
  225.    {
  226.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  227.       {
  228.          png_push_save_buffer(png_ptr);
  229.          return;
  230.       }
  231.  
  232.       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
  233.    }
  234. #endif
  235. #if defined(PNG_READ_tRNS_SUPPORTED)
  236.    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
  237.    {
  238.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  239.       {
  240.          png_push_save_buffer(png_ptr);
  241.          return;
  242.       }
  243.  
  244.       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
  245.    }
  246. #endif
  247. #if defined(PNG_READ_bKGD_SUPPORTED)
  248.    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
  249.    {
  250.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  251.       {
  252.          png_push_save_buffer(png_ptr);
  253.          return;
  254.       }
  255.  
  256.       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
  257.    }
  258. #endif
  259. #if defined(PNG_READ_hIST_SUPPORTED)
  260.    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
  261.    {
  262.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  263.       {
  264.          png_push_save_buffer(png_ptr);
  265.          return;
  266.       }
  267.  
  268.       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
  269.    }
  270. #endif
  271. #if defined(PNG_READ_pHYs_SUPPORTED)
  272.    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
  273.    {
  274.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  275.       {
  276.          png_push_save_buffer(png_ptr);
  277.          return;
  278.       }
  279.  
  280.       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
  281.    }
  282. #endif
  283. #if defined(PNG_READ_oFFs_SUPPORTED)
  284.    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
  285.    {
  286.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  287.       {
  288.          png_push_save_buffer(png_ptr);
  289.          return;
  290.       }
  291.  
  292.       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
  293.    }
  294. #endif
  295. #if defined(PNG_READ_tIME_SUPPORTED)
  296.    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
  297.    {
  298.       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  299.       {
  300.          png_push_save_buffer(png_ptr);
  301.          return;
  302.       }
  303.  
  304.       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
  305.    }
  306. #endif
  307. #if defined(PNG_READ_tEXt_SUPPORTED)
  308.    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
  309.    {
  310.       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
  311.    }
  312. #endif
  313. #if defined(PNG_READ_zTXt_SUPPORTED)
  314.    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
  315.    {
  316.       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
  317.    }
  318. #endif
  319.    else
  320.    {
  321.       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
  322.    }
  323.  
  324.    png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
  325. }
  326.  
  327. void
  328. png_push_crc_skip(png_structp png_ptr, png_uint_32 length)
  329. {
  330.    png_ptr->process_mode = PNG_SKIP_MODE;
  331.    png_ptr->skip_length = length;
  332. }
  333.  
  334. void
  335. png_push_skip(png_structp png_ptr)
  336. {
  337.    if (png_ptr->skip_length && png_ptr->save_buffer_size)
  338.    {
  339.       png_uint_32 save_size;
  340.  
  341.       if (png_ptr->skip_length < png_ptr->save_buffer_size)
  342.          save_size = png_ptr->skip_length;
  343.       else
  344.          save_size = png_ptr->save_buffer_size;
  345.  
  346.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  347.  
  348.       png_ptr->skip_length -= save_size;
  349.       png_ptr->buffer_size -= save_size;
  350.       png_ptr->save_buffer_size -= save_size;
  351.       png_ptr->save_buffer_ptr += (png_size_t)save_size;
  352.    }
  353.    if (png_ptr->skip_length && png_ptr->current_buffer_size)
  354.    {
  355.       png_uint_32 save_size;
  356.  
  357.       if (png_ptr->skip_length < png_ptr->current_buffer_size)
  358.          save_size = png_ptr->skip_length;
  359.       else
  360.          save_size = png_ptr->current_buffer_size;
  361.  
  362.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  363.  
  364.       png_ptr->skip_length -= save_size;
  365.       png_ptr->buffer_size -= save_size;
  366.       png_ptr->current_buffer_size -= save_size;
  367.       png_ptr->current_buffer_ptr += (png_size_t)save_size;
  368.    }
  369.    if (!png_ptr->skip_length)
  370.    {
  371.       if (png_ptr->buffer_size < 4)
  372.       {
  373.          png_push_save_buffer(png_ptr);
  374.          return;
  375.       }
  376.  
  377.       png_crc_finish(png_ptr, 0);
  378.  
  379.       if (png_ptr->mode & PNG_AFTER_IDAT)
  380.          png_ptr->process_mode = PNG_READ_END_MODE;
  381.       else
  382.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  383.    }
  384. }
  385.  
  386. void
  387. png_push_fill_buffer(png_structp png_ptr, png_bytep buffer,
  388.    png_uint_32 length)
  389. {
  390.    png_bytep ptr;
  391.  
  392.    ptr = buffer;
  393.    if (png_ptr->save_buffer_size)
  394.    {
  395.       png_uint_32 save_size;
  396.  
  397.       if (length < png_ptr->save_buffer_size)
  398.          save_size = length;
  399.       else
  400.          save_size = png_ptr->save_buffer_size;
  401.  
  402.       png_memcpy(ptr, png_ptr->save_buffer_ptr, (png_size_t)save_size);
  403.       length -= save_size;
  404.       ptr += (png_size_t)save_size;
  405.       png_ptr->buffer_size -= save_size;
  406.       png_ptr->save_buffer_size -= save_size;
  407.       png_ptr->save_buffer_ptr += (png_size_t)save_size;
  408.    }
  409.    if (length && png_ptr->current_buffer_size)
  410.    {
  411.       png_uint_32 save_size;
  412.  
  413.       if (length < png_ptr->current_buffer_size)
  414.          save_size = length;
  415.       else
  416.          save_size = png_ptr->current_buffer_size;
  417.  
  418.       png_memcpy(ptr, png_ptr->current_buffer_ptr, (png_size_t)save_size);
  419.       png_ptr->buffer_size -= save_size;
  420.       png_ptr->current_buffer_size -= save_size;
  421.       png_ptr->current_buffer_ptr += (png_size_t)save_size;
  422.    }
  423. }
  424.  
  425. void
  426. png_push_save_buffer(png_structp png_ptr)
  427. {
  428.    if (png_ptr->save_buffer_size)
  429.    {
  430.       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
  431.       {
  432.          int i;
  433.          png_bytep sp;
  434.          png_bytep dp;
  435.  
  436.          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
  437.             i < png_ptr->save_buffer_size;
  438.             i++, sp++, dp++)
  439.          {
  440.             *dp = *sp;
  441.          }
  442.       }
  443.    }
  444.    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
  445.       png_ptr->save_buffer_max)
  446.    {
  447.       png_uint_32 new_max;
  448.       png_bytep old_buffer;
  449.  
  450.       new_max = (int)(png_ptr->save_buffer_size +
  451.          png_ptr->current_buffer_size + 256);
  452.       old_buffer = png_ptr->save_buffer;
  453.       png_ptr->save_buffer = (png_bytep)
  454.          png_malloc(png_ptr, new_max);
  455.       png_memcpy(png_ptr->save_buffer, old_buffer,
  456.          (png_size_t)png_ptr->save_buffer_size);
  457.       png_free(png_ptr, old_buffer);
  458.         png_ptr->save_buffer_max = new_max;
  459.    }
  460.    if (png_ptr->current_buffer_size)
  461.    {
  462.       png_memcpy(png_ptr->save_buffer +
  463.          (png_size_t)png_ptr->save_buffer_size,
  464.          png_ptr->current_buffer_ptr,
  465.          (png_size_t)png_ptr->current_buffer_size);
  466.       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
  467.       png_ptr->current_buffer_size = 0;
  468.    }
  469.    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
  470.    png_ptr->buffer_size = 0;
  471. }
  472.  
  473. void
  474. png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
  475.    png_uint_32 buffer_length)
  476. {
  477.    png_ptr->current_buffer = buffer;
  478.    png_ptr->current_buffer_size = buffer_length;
  479.    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
  480.    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
  481. }
  482.  
  483. void
  484. png_push_read_IDAT(png_structp png_ptr)
  485. {
  486.    if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
  487.    {
  488.       png_byte chunk_length[4];
  489.  
  490.       if (png_ptr->buffer_size < 8)
  491.       {
  492.          png_push_save_buffer(png_ptr);
  493.          return;
  494.       }
  495.  
  496.       png_push_fill_buffer(png_ptr, chunk_length, 4);
  497.       png_ptr->push_length = png_get_uint_32(chunk_length);
  498.  
  499.       png_reset_crc(png_ptr);
  500.       png_push_fill_buffer(png_ptr, png_ptr->chunk_name, 4);
  501.       png_calculate_crc(png_ptr, chunk_length, 4);
  502.       png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
  503.  
  504.       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  505.       {
  506.          png_ptr->process_mode = PNG_READ_END_MODE;
  507.          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  508.             png_error(png_ptr, "Not enough compressed data");
  509.          return;
  510.       }
  511.  
  512.       png_ptr->idat_size = png_ptr->push_length;
  513.    }
  514.    if (png_ptr->idat_size && png_ptr->save_buffer_size)
  515.    {
  516.       png_uint_32 save_size;
  517.  
  518.       if (png_ptr->idat_size < png_ptr->save_buffer_size)
  519.          save_size = png_ptr->idat_size;
  520.       else
  521.          save_size = png_ptr->save_buffer_size;
  522.  
  523.       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  524.       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
  525.  
  526.       png_ptr->idat_size -= save_size;
  527.       png_ptr->buffer_size -= save_size;
  528.       png_ptr->save_buffer_size -= save_size;
  529.       png_ptr->save_buffer_ptr += (png_size_t)save_size;
  530.    }
  531.    if (png_ptr->idat_size && png_ptr->current_buffer_size)
  532.    {
  533.       png_uint_32 save_size;
  534.  
  535.       if (png_ptr->idat_size < png_ptr->current_buffer_size)
  536.          save_size = png_ptr->idat_size;
  537.       else
  538.          save_size = png_ptr->current_buffer_size;
  539.  
  540.       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  541.       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
  542.  
  543.       png_ptr->idat_size -= save_size;
  544.       png_ptr->buffer_size -= save_size;
  545.       png_ptr->current_buffer_size -= save_size;
  546.       png_ptr->current_buffer_ptr += (png_size_t)save_size;
  547.    }
  548.    if (!png_ptr->idat_size)
  549.    {
  550.       if (png_ptr->buffer_size < 4)
  551.       {
  552.          png_push_save_buffer(png_ptr);
  553.          return;
  554.       }
  555.  
  556.       png_crc_finish(png_ptr, 0);
  557.       png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
  558.    }
  559. }
  560.  
  561. void
  562. png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
  563.    png_uint_32 buffer_length)
  564. {
  565.    int ret;
  566.  
  567.    if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
  568.       png_error(png_ptr, "Extra compression data");
  569.  
  570.    png_ptr->zstream.next_in = buffer;
  571.    png_ptr->zstream.avail_in = (uInt)buffer_length;
  572.    do
  573.    {
  574.       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  575.       if (ret == Z_STREAM_END)
  576.       {
  577.          if (png_ptr->zstream.avail_in)
  578.             png_error(png_ptr, "Extra compressed data");
  579.          if (!png_ptr->zstream.avail_out)
  580.          {
  581.             png_push_process_row(png_ptr);
  582.          }
  583.          png_ptr->mode = PNG_AFTER_IDAT;
  584.          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  585.          break;
  586.       }
  587.       if (ret != Z_OK)
  588.          png_error(png_ptr, "Decompression Error");
  589.       if (!(png_ptr->zstream.avail_out))
  590.       {
  591.          png_push_process_row(png_ptr);
  592.          png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
  593.          png_ptr->zstream.next_out = png_ptr->row_buf;
  594.       }
  595.  
  596.    } while (png_ptr->zstream.avail_in);
  597. }
  598.  
  599. void
  600. png_push_process_row(png_structp png_ptr)
  601. {
  602.    png_ptr->row_info.color_type = png_ptr->color_type;
  603.    png_ptr->row_info.width = png_ptr->iwidth;
  604.    png_ptr->row_info.channels = png_ptr->channels;
  605.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  606.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  607.    png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
  608.       (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
  609.  
  610.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  611.       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  612.       (int)(png_ptr->row_buf[0]));
  613.  
  614.    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1);
  615.  
  616.    if (png_ptr->transformations)
  617.       png_do_read_transformations(png_ptr);
  618.  
  619. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  620.    /* blow up interlaced rows to full size */
  621.    if (png_ptr->interlaced &&
  622.       (png_ptr->transformations & PNG_INTERLACE))
  623.    {
  624.       if (png_ptr->pass < 6)
  625.          png_do_read_interlace(&(png_ptr->row_info),
  626.             png_ptr->row_buf + 1, png_ptr->pass);
  627.  
  628.       switch (png_ptr->pass)
  629.       {
  630.          case 0:
  631.          {
  632.             int i;
  633.             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  634.             {
  635.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  636.                png_read_push_finish_row(png_ptr);
  637.             }
  638.             break;
  639.          }
  640.          case 1:
  641.          {
  642.             int i;
  643.             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  644.             {
  645.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  646.                png_read_push_finish_row(png_ptr);
  647.             }
  648.             if (png_ptr->pass == 2)
  649.             {
  650.                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  651.                {
  652.                   png_push_have_row(png_ptr, NULL);
  653.                   png_read_push_finish_row(png_ptr);
  654.                }
  655.             }
  656.             break;
  657.          }
  658.          case 2:
  659.          {
  660.             int i;
  661.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  662.             {
  663.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  664.                png_read_push_finish_row(png_ptr);
  665.             }
  666.             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  667.             {
  668.                png_push_have_row(png_ptr, NULL);
  669.                png_read_push_finish_row(png_ptr);
  670.             }
  671.             break;
  672.          }
  673.          case 3:
  674.          {
  675.             int i;
  676.             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  677.             {
  678.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  679.                png_read_push_finish_row(png_ptr);
  680.             }
  681.             if (png_ptr->pass == 4)
  682.             {
  683.                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  684.                {
  685.                   png_push_have_row(png_ptr, NULL);
  686.                   png_read_push_finish_row(png_ptr);
  687.                }
  688.             }
  689.             break;
  690.          }
  691.          case 4:
  692.          {
  693.             int i;
  694.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  695.             {
  696.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  697.                png_read_push_finish_row(png_ptr);
  698.             }
  699.             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  700.             {
  701.                png_push_have_row(png_ptr, NULL);
  702.                png_read_push_finish_row(png_ptr);
  703.             }
  704.             break;
  705.          }
  706.          case 5:
  707.          {
  708.             int i;
  709.             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  710.             {
  711.                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  712.                png_read_push_finish_row(png_ptr);
  713.             }
  714.             if (png_ptr->pass == 6)
  715.             {
  716.                png_push_have_row(png_ptr, NULL);
  717.                png_read_push_finish_row(png_ptr);
  718.             }
  719.             break;
  720.          }
  721.          case 6:
  722.          {
  723.             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  724.             png_read_push_finish_row(png_ptr);
  725.             if (png_ptr->pass != 6)
  726.                break;
  727.             png_push_have_row(png_ptr, NULL);
  728.             png_read_push_finish_row(png_ptr);
  729.          }
  730.       }
  731.    }
  732.    else
  733. #endif
  734.    {
  735.       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  736.       png_read_push_finish_row(png_ptr);
  737.    }
  738. }
  739.  
  740. void
  741. png_read_push_finish_row(png_structp png_ptr)
  742. {
  743.    png_ptr->row_number++;
  744.    if (png_ptr->row_number < png_ptr->num_rows)
  745.       return;
  746.  
  747.    if (png_ptr->interlaced)
  748.    {
  749.       png_ptr->row_number = 0;
  750.       png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  751.       do
  752.       {
  753.          png_ptr->pass++;
  754.          if (png_ptr->pass >= 7)
  755.             break;
  756.          png_ptr->iwidth = (png_ptr->width +
  757.             png_pass_inc[png_ptr->pass] - 1 -
  758.             png_pass_start[png_ptr->pass]) /
  759.             png_pass_inc[png_ptr->pass];
  760.          png_ptr->irowbytes = ((png_ptr->iwidth *
  761.             png_ptr->pixel_depth + 7) >> 3) + 1;
  762.          if (!(png_ptr->transformations & PNG_INTERLACE))
  763.          {
  764.             png_ptr->num_rows = (png_ptr->height +
  765.                png_pass_yinc[png_ptr->pass] - 1 -
  766.                png_pass_ystart[png_ptr->pass]) /
  767.                png_pass_yinc[png_ptr->pass];
  768.             if (!(png_ptr->num_rows))
  769.                continue;
  770.          }
  771.          if (png_ptr->transformations & PNG_INTERLACE)
  772.             break;
  773.       } while (png_ptr->iwidth == 0);
  774.    }
  775. }
  776.  
  777. #if defined(PNG_READ_tEXt_SUPPORTED)
  778. void
  779. png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  780. {
  781.    if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
  782.       png_error(png_ptr, "Out of place tEXt");
  783.  
  784.    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
  785.    png_ptr->current_text[(png_size_t)length] = '\0';
  786.    png_ptr->current_text_ptr = png_ptr->current_text;
  787.    png_ptr->current_text_size = length;
  788.    png_ptr->current_text_left = length;
  789.    png_ptr->process_mode = PNG_READ_tEXt_MODE;
  790. }
  791.  
  792. void
  793. png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
  794. {
  795.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  796.    {
  797.       png_uint_32 text_size;
  798.  
  799.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  800.          text_size = png_ptr->buffer_size;
  801.       else
  802.          text_size = png_ptr->current_text_left;
  803.       png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  804.          text_size);
  805.       png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  806.          text_size);
  807.       png_ptr->current_text_left -= text_size;
  808.       png_ptr->current_text_ptr += (png_size_t)text_size;
  809.    }
  810.    if (!(png_ptr->current_text_left))
  811.    {
  812.       png_charp text;
  813.       png_charp key;
  814.  
  815.       if (png_ptr->buffer_size < 4)
  816.       {
  817.          png_push_save_buffer(png_ptr);
  818.          return;
  819.       }
  820.  
  821.       png_crc_finish(png_ptr, 0);
  822.  
  823.       key = png_ptr->current_text;
  824.       png_ptr->current_text = 0;
  825.  
  826.       for (text = key; *text; text++)
  827.          /* empty loop */ ;
  828.  
  829.       if (text != key + (png_size_t)png_ptr->current_text_size)
  830.          text++;
  831.  
  832.       png_read_tEXt(png_ptr, info_ptr, key, text,
  833.          png_ptr->current_text_size - (text - key));
  834.  
  835.       if (png_ptr->mode == PNG_AFTER_IDAT)
  836.       {
  837.          png_ptr->process_mode = PNG_READ_END_MODE;
  838.       }
  839.       else
  840.       {
  841.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  842.       }
  843.    }
  844. }
  845. #endif
  846.  
  847. #if defined(PNG_READ_zTXt_SUPPORTED)
  848. void
  849. png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  850. {
  851.    if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
  852.       png_error(png_ptr, "Out of place zTXt");
  853.  
  854.    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
  855.    png_ptr->current_text[(png_size_t)length] = '\0';
  856.    png_ptr->current_text_ptr = png_ptr->current_text;
  857.    png_ptr->current_text_size = length;
  858.    png_ptr->current_text_left = length;
  859.    png_ptr->process_mode = PNG_READ_zTXt_MODE;
  860. }
  861.  
  862. void
  863. png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
  864. {
  865.    if (png_ptr->buffer_size && png_ptr->current_text_left)
  866.    {
  867.       png_uint_32 text_size;
  868.  
  869.       if (png_ptr->buffer_size < png_ptr->current_text_left)
  870.          text_size = png_ptr->buffer_size;
  871.       else
  872.          text_size = png_ptr->current_text_left;
  873.       png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  874.          text_size);
  875.       png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  876.          text_size);
  877.       png_ptr->current_text_left -= text_size;
  878.       png_ptr->current_text_ptr += (png_size_t)text_size;
  879.    }
  880.    if (!(png_ptr->current_text_left))
  881.    {
  882.       png_charp text;
  883.       png_charp key;
  884.       int ret;
  885.       png_uint_32 text_size, key_size;
  886.  
  887.       if (png_ptr->buffer_size < 4)
  888.       {
  889.          png_push_save_buffer(png_ptr);
  890.          return;
  891.       }
  892.  
  893.       png_crc_finish(png_ptr, 0);
  894.  
  895.       key = png_ptr->current_text;
  896.       png_ptr->current_text = 0;
  897.  
  898.       for (text = key; *text; text++)
  899.          /* empty loop */ ;
  900.  
  901.       /* zTXt can't have zero text */
  902.       if (text == key + (png_size_t)png_ptr->current_text_size)
  903.       {
  904.          png_free(png_ptr, key);
  905.          return;
  906.       }
  907.  
  908.       text++;
  909.  
  910.       if (*text) /* check compression byte */
  911.       {
  912.          png_free(png_ptr, key);
  913.          return;
  914.       }
  915.  
  916.       text++;
  917.  
  918.       png_ptr->zstream.next_in = (png_bytep )text;
  919.       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
  920.          (text - key));
  921.       png_ptr->zstream.next_out = png_ptr->zbuf;
  922.       png_ptr->zstream.avail_out = (png_size_t)png_ptr->zbuf_size;
  923.  
  924.       key_size = text - key;
  925.       text_size = 0;
  926.       text = NULL;
  927.       ret = Z_STREAM_END;
  928.  
  929.       while (png_ptr->zstream.avail_in)
  930.       {
  931.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  932.          if (ret != Z_OK && ret != Z_STREAM_END)
  933.          {
  934.             inflateReset(&png_ptr->zstream);
  935.             png_ptr->zstream.avail_in = 0;
  936.             png_free(png_ptr, key);
  937.             png_free(png_ptr, text);
  938.             return;
  939.          }
  940.          if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
  941.          {
  942.             if (!text)
  943.             {
  944.                text = (png_charp)png_malloc(png_ptr,
  945.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out +
  946.                      key_size + 1);
  947.                png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
  948.                   (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
  949.                png_memcpy(text, key, (png_size_t)key_size);
  950.                text_size = key_size + (png_size_t)png_ptr->zbuf_size -
  951.                   png_ptr->zstream.avail_out;
  952.                *(text + (png_size_t)text_size) = '\0';
  953.             }
  954.             else
  955.             {
  956.                png_charp tmp;
  957.  
  958.                tmp = text;
  959.                text = png_malloc(png_ptr, text_size +
  960.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1);
  961.                png_memcpy(text, tmp, (png_size_t)text_size);
  962.                png_free(png_ptr, tmp);
  963.                png_memcpy(text + (png_size_t)text_size, png_ptr->zbuf,
  964.                   (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
  965.                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  966.                *(text + (png_size_t)text_size) = '\0';
  967.             }
  968.             if (ret != Z_STREAM_END)
  969.             {
  970.                png_ptr->zstream.next_out = png_ptr->zbuf;
  971.                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  972.             }
  973.          }
  974.          else
  975.          {
  976.             break;
  977.          }
  978.  
  979.          if (ret == Z_STREAM_END)
  980.             break;
  981.       }
  982.  
  983.       inflateReset(&png_ptr->zstream);
  984.       png_ptr->zstream.avail_in = 0;
  985.  
  986.       if (ret != Z_STREAM_END)
  987.       {
  988.          png_free(png_ptr, key);
  989.          png_free(png_ptr, text);
  990.          return;
  991.       }
  992.  
  993.       png_free(png_ptr, key);
  994.       key = text;
  995.       text += (png_size_t)key_size;
  996.       text_size -= key_size;
  997.  
  998.       png_read_zTXt(png_ptr, info_ptr, key, text, text_size, 0);
  999.       if (png_ptr->mode == PNG_AFTER_IDAT)
  1000.       {
  1001.          png_ptr->process_mode = PNG_READ_END_MODE;
  1002.       }
  1003.       else
  1004.       {
  1005.          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  1006.       }
  1007.    }
  1008. }
  1009. #endif
  1010.  
  1011. /* This function is called when we haven't found a handler for this
  1012.    chunk.  In the future we will have code here which can handle
  1013.    user-defined callback functions for unknown chunks before they are
  1014.    ignored or cause an error.  If there isn't a problem with the
  1015.    chunk itself (ie a bad chunk name or a critical chunk), the chunk
  1016.    is (currently) silently ignored. */
  1017. void
  1018. png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1019. {
  1020.    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  1021.  
  1022.    if (!(png_ptr->chunk_name[0] & 0x20))
  1023.    {
  1024.       char msg[40];
  1025.  
  1026.       sprintf(msg, "Unknown critical chunk %s", png_ptr->chunk_name);
  1027.       png_error(png_ptr, msg);
  1028.    }
  1029.  
  1030.    png_push_crc_skip(png_ptr, length);
  1031. }
  1032.  
  1033. void
  1034. png_push_have_info(png_structp png_ptr, png_infop info_ptr)
  1035. {
  1036.    if (png_ptr->info_fn)
  1037.       (*(png_ptr->info_fn))(png_ptr, info_ptr);
  1038. }
  1039.  
  1040. void
  1041. png_push_have_end(png_structp png_ptr, png_infop info_ptr)
  1042. {
  1043.    if (png_ptr->end_fn)
  1044.       (*(png_ptr->end_fn))(png_ptr, info_ptr);
  1045. }
  1046.  
  1047. void
  1048. png_push_have_row(png_structp png_ptr, png_bytep row)
  1049. {
  1050.    if (png_ptr->row_fn)
  1051.       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1052.          (int)png_ptr->pass);
  1053. }
  1054.  
  1055. void
  1056. png_progressive_combine_row (png_structp png_ptr,
  1057.    png_bytep old_row, png_bytep new_row)
  1058. {
  1059.    if (new_row)
  1060.       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1061. }
  1062.  
  1063. void
  1064. png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1065.    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1066.    png_progressive_end_ptr end_fn)
  1067. {
  1068.    png_ptr->info_fn = info_fn;
  1069.    png_ptr->row_fn = row_fn;
  1070.    png_ptr->end_fn = end_fn;
  1071.  
  1072.    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1073. }
  1074.  
  1075. png_voidp
  1076. png_get_progressive_ptr(png_structp png_ptr)
  1077. {
  1078.    return png_ptr->io_ptr;
  1079. }
  1080.  
  1081. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  1082.  
  1083.